home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / doc / romable.doc < prev    next >
Text File  |  1994-02-13  |  16KB  |  438 lines

  1.  
  2. romable/romable                           romable/romable
  3.  
  4.                   ROMABLE.DOC
  5.  
  6.                GENERATING ROMABLE FIRMWARE
  7.  
  8.                   REFERENCES
  9.  
  10.     Please refer to the following DCC options:
  11.  
  12.     -pi    generate position independant code.  All code references
  13.         forced to PC-relative
  14.  
  15.     -pr    generate residentable position independant code.  Unless
  16.         -mw is specified A4 relative addressing is used for data
  17.         items.    All code references forced  to PC-relative.
  18.  
  19.     -ma    specify that initialized data + bss will be hardwired to
  20.         a known address
  21.  
  22.     -mw    specify that initialized data + bss will be hardwired to
  23.         a known address and all of data + bss occurs somewhere
  24.         within the first 32KBytes of the address space
  25.         (0x0000-0x7FFF).  Also allows DICE to use A4 as a register
  26.         variable.
  27.  
  28.     -ms    const items go into EPROM in local cases
  29.  
  30.     -mS    const items go into EPROM in local and external cases
  31.  
  32.     The following documentation may appear confusing, but only because so
  33.     many possibilities exist when one intends to put code in ROM.  When you
  34.     are in doubt, it is usually a good idea to write a small test source
  35.     file, compile it, link it with symbols, and then look at the resulting
  36.     executable with DOBJ.
  37.  
  38.  
  39.               MAKING ROMABLE PROGRAMS
  40.  
  41.     DICE has the capability to generate ROMABLE programs.  That is, program
  42.     binaries that you can use to directly burn an EPROM.  When generating
  43.     ROMABLE code you have more data model options available to you.  The
  44.     basic idea of ROMd code is as follows:
  45.                ________________
  46. FIXED ADDRESS = EPROM |            |
  47.               | 68000 vectors  |    const data objects
  48.               |----------------|
  49.               |     CODE       |
  50.               |----------------|
  51.               |  const DATA    |    string constants and other
  52.               |            |    const items, stays in eprom.
  53.               |----------------|
  54.               | read-only copy |
  55.               | of initialized |    this is copied to a working
  56.               | data           |    RAM copy by the reset code
  57.               |________________|
  58.  
  59.                ________________
  60. FIXED ADDRESS = RAM   | run-time copy  |    (copied from EPROM by startup)
  61.               | of initialized |
  62.               | data           |
  63.               |----------------|    (cleared by EPROM startup)
  64.               | run-time BSS   |
  65.               |________________|
  66.  
  67.  
  68.     From the above you have two basic choices in terms of where your
  69.     RUN-TIME DATA is based.  If your RAM exists in low-memory
  70.     (0x0000-0x7FFF) you may choose to compile your code to use the
  71.     ABSOLUTE-WORD addressing mode.  This modes takes the same space as the
  72.     A4-RELATIVE addressing mode yet does not require use of the A4 register
  73.     and, in fact, the A4 register will then be available for use as a
  74.     register variable.
  75.  
  76.     If you have minimal RAM in low-memory or your DATA+BSS is larger than
  77.     32KBytes (yes, that's 32KBytes people, not 64KBytes), then you will
  78.     have to choose either the formal large-data model or the A4-relative
  79.     small data model.  If you initialized data is over 64KBytes you can
  80.     still use the small-data model for most objects by using the __far
  81.     keyword judiciously.
  82.  
  83.     NOTE: in all cases you can allocate or generate points for any ram
  84.     location, this just refers to accesses of declared variables!  Pointers
  85.     are always 32 bits.
  86.  
  87.     model        options     advantages          disadvantages
  88.  
  89.     absolute-word    -mw    -ms    no need for A4          low 32KBytes only
  90.                     A4 available as
  91.                     reg variable
  92.  
  93.     small-data        -ma    -ms    RAM can be anywhere   requires A4
  94.                                   must use __geta4
  95.  
  96.     large-data        -ma -mD -ms    RAM can be anywhere   code is larger
  97.                                   libs must all be
  98.                                   large-data
  99.  
  100.  
  101.                 CODE MODEL
  102.  
  103.     The CODE MODEL is normally left at PC-relative and should not present a
  104.     problem.
  105.  
  106.                 CONST DATA
  107.  
  108.     You want to use the -ms option or even the -mS option (see DCC.DOC for
  109.     the differences).  This will place all string constants in EPROM and
  110.     IN THE CODE SEGMENT, thus this initialized data will NOT take up space
  111.     in RAM.  Any 'const' initialized data will be placed in the code segment
  112.     and thus in EPROM.    Any non-const initialized data will be copied from
  113.     EPROM into RAM by your reset-startup code.
  114.  
  115.     Any tables that you declare that you will never modify should be
  116.     declared const so they reside in EPROM and do not take up space in RAM.
  117.     On the otherhand, if your EPROM is running 6 wait states and your RAM
  118.     is running 0 you might consider not using 'const'.... assuming you have
  119.     a lot of RAM.
  120.  
  121.     When your code is less than 32KBytes big you can use -pi or -pr and
  122.     should definitely use -mS.    When your code is larger than 32KBytes you
  123.     cannot use -mS unless you are absolutely positive pc-relative const
  124.     data references do not exceed the word-relative range.
  125.  
  126.               RESET VECTOR, DATA MODEL SETUP
  127.  
  128.     If your EPROM is mapped into low memory on boot you can declare a vector
  129.     table by declaring a CONST LONG array as the first data object in the
  130.     first object module that you link to create the executable:
  131.  
  132.     const long ROMVectorTable[] = {
  133.         InitialSSP,
  134.         ResetVector,
  135.           .
  136.           .
  137.           .
  138.     };
  139.  
  140.     Remember, this must be the first data declaration in the first object
  141.     module!!!  If you are using the A4-RELATIVE small-data model you must
  142.     qualify your ResetVector with the __geta4 type qualifier to set up A4.
  143.  
  144.     In most cases you will want ResetVector to point to some assembly which
  145.     initializes your RAM DATA & BSS before calling C code.  The assembly
  146.     normally looks like this (this would be the second object in the link):
  147.  
  148.         ;   RESET exception, copy initialized data to RAM and clear
  149.         ;   BSS area before calling rom_main()
  150.         ;
  151.         ;   Assumes less than 256KBytes of data and 256KBytes of BSS
  152.  
  153.         xref    __DATA_BAS        ; linker generated symbols
  154.         xref    __ABSOLUTE_BAS
  155.         xref    __DATA_LEN
  156.         xref    __BSS_LEN
  157.         xref    _rom_main
  158.  
  159. _ResetVector
  160.         lea    __DATA_BAS,A0        ; ROM data
  161.         lea    __ABSOLUTE_BAS,A1   ; RAM data
  162.         move.w    #__DATA_LEN,D0        ; long words of data
  163.         bra    trentry
  164. trloop        move.l    (A0)+,(A1)+         ; copy EPROM copy to run-time
  165. trentry     dbf    D0,trloop        ; RAM copy.
  166.  
  167.         move.w    #__BSS_LEN,D0        ; long words of BSS (follows data)
  168.         moveq.l #0,D1
  169.         bra    trbentry
  170. trbloop     move.l    D1,(A1)+            ; clear run-time RAM
  171. trbentry    dbf    D0,trbloop
  172.  
  173.         jmp    _rom_main(pc)
  174.  
  175.     Where rom_main() is your C main routine qualified with __geta4 (if you
  176.     are using the A4-RELATIVE data model).  Any special items, such as
  177.     the EPROM getting mapped at reset, must be dealt with as well, usually
  178.     before the reset code sets up the run-time enviroment.
  179.  
  180.     If you are using the ABSOLUTE-WORD data model DO NOT USE __GETA4!
  181.     Specifically, the -mw option TELLS DICE THAT A4 IS FREE FOR USE AS A
  182.     NORMAL REGISTER VARIABLE.  This gives you an extra register variable if
  183.     you haven't guessed!
  184.  
  185.                    EXAMPLE PROGRAM
  186.  
  187.     Assume the above assembly module has been assembled and is called
  188.     'romc.o'.  The following C program is called 'test.c'.  In all cases
  189.     the code may start anywhere.
  190.  
  191.     Also, in all cases note that ROMC.O is specified AFTER test in the
  192.     DCC line (that also serves as the link line).  This is because for
  193.     a standalone product we want our CONST data object that is the
  194.     ROM VECTOR TABLE to be first.  Of course, if you put the ROM VECTOR
  195.     TABLE in ROMC.A instead of TEST.C then ROMC.A would go first.  To
  196.     put the ROM VECTOR TABLE in ROMC.A it should be the first data
  197.     object declarations (dc.l's) in the CODE segment.
  198.  
  199.  
  200.     (1) SMALL-DATA-MODEL
  201.  
  202.     extern void TrapReset();
  203.     extern char SSp[512];
  204.  
  205.     const long RomVectors[] = { (long)SSp, (long)TrapReset };
  206.  
  207.     char SSp[512];        /*    our supervisor stack in BSS */
  208.  
  209.     __geta4 void
  210.     rom_main()
  211.     {
  212.         short i;
  213.  
  214.         for (;;) {
  215.         for (i = 0; i < 10000; ++i) {
  216.             <do something here with  i>
  217.         }
  218.         }
  219.     }
  220.                     note, ram can be beyond 64K
  221.                     v
  222.  
  223.     COMPILE:    dcc test.c romc.o -ma 0x10000 -o t:test -r -v -lrom
  224.             romable t:test -o t:test.bin -D 0x10000 -C 0x0
  225.             burn eprom using test.bin
  226.  
  227.  
  228.     (2) ABSOLUTE WORD DATA MODEL
  229.  
  230.     The source code is the same except you do not need __geta4.  Here
  231.     I am assuming RAM starts at, say, 0x2000.
  232.  
  233.     void
  234.     rom_main()
  235.     {
  236.         ...
  237.     }
  238.  
  239.     COMPILE:    dcc test.c romc.o -mw 0x2000 -o t:test -r -lrom
  240.             romable t:test -o t:test.bin -D 0x2000 -C 0x0
  241.             burn eprom using test.bin
  242.  
  243.     (3) ABSOLUTE LONG DATA MODEL
  244.  
  245.     The source code is the same as for (2).  Here the RAM may start
  246.     anywhere (also true in (1)).
  247.  
  248.     COMPILE:    dcc test.c romc.o -ma 0x10080 -o t:test -r -lrom
  249.             romable t:test -o t:test.bin -D 0x10080 -C 0
  250.             burn eprom using test.bin
  251.  
  252.     (4) EXAMPLE OF EPROM INITIALLY MAPPED AT 0x0000 BUT REMAPPABLE TO
  253.     SOMEWHERE ELSE
  254.  
  255.     In this case the assembly, ROMC.A, must relocate the EPROM back
  256.     to where it should be before initializing the data segment.  Here
  257.     your initial CONST data is the EPROM VECTOR TABLE, and your initial
  258.     non-CONST INITIALIZED data (because BSS gets stuck after all
  259.     initialized data) will be your RAM VECTOR TABLE.
  260.  
  261.     In this example I assume that RAM will be mapped into 0x0000-
  262.     by the time rom_main() gets called.  Compilation depends on the
  263.     data model.  The example below uses the ABSOLUTE WORD data model.
  264.  
  265.     extern void TrapReset();
  266.     extern char SSp[512];
  267.  
  268.     const long RomVectors[] = { (long)SSp, (long)TrapReset };
  269.     long RamVectors[] = { (long)SSp, (long)TrapReset, ... };
  270.  
  271.     char SSp[512];        /*    our supervisor stack in BSS */
  272.  
  273.     void
  274.     rom_main()
  275.     {
  276.         ...
  277.     }
  278.  
  279.     In this compilation example I am assuming the RAM will be at 0x0000 and
  280.     the ROM, say, at 0x20000 (above the 64KBmark)
  281.  
  282.     COMPILE:    dcc test.c romc.o -mw 0 -o t:test -r -lrom
  283.             romable t:test -o t:test.bin -D 0 -C 0x20000
  284.             burn eprom using test.bin
  285.  
  286.                 USING ROM.LIB
  287.  
  288.     ROM.LIB is generated from LIB/FILES.ROM3LIB and contains those modules
  289.     from C.LIB that do not declare any variables and are position
  290.     independant.  Modules in the library are entirely position independant.
  291.     If you use library calls instead of macros in <ctype.h> for ctype
  292.     functions those are position independant as well ... they use
  293.     pc-relative to access the lookup tables (which are declared const).
  294.  
  295.     Nothing in ROM.LIB declares any data variables.  The idea is to link
  296.     your code with ROM.LIB instead of C.LIB to ensure that incompatible
  297.     routines are never included by mistake.
  298.  
  299.     Warning: If you want position independant code you must compile with
  300.     -pi or -mS, especially when accessing <ctype.h> macros.  Accessing
  301.     <ctype.h> macros and not using either the above options will result in
  302.     absolute-code references to ctype's lookup tables.
  303.  
  304.     ------------------------------------------------------------------------
  305.                 MAKING RAM MODULES
  306.  
  307.     Generating a binary image for an executable that is meant to run from
  308.     RAM instead EPROM is relatively easy.  In many cases you want only a
  309.     single copy of the data (instead of two copies as in EPROM modules..
  310.     the permanent initialized data in EPROM and the run-time data+bss in
  311.     RAM).  This means that the program is not-reentrant... once an
  312.     initialized data variable is modified it stays modified.  If this is
  313.     not desireable you can use the same methods as were described for
  314.     making EPROM code combined with methods (see LIB/AMIGA/C_PR.A) to
  315.     allocate the data space run-time.
  316.  
  317.     If you want to generate resident style modules use the small-data model
  318.     version in the previous section 'MAKING ROMABLE PROGRAMS' and simply
  319.     apply the concept of downloading such a module into RAM instead of ROM.
  320.     It is especially easy when the code is completely position independant
  321.     because your firmware does not have to deal with relocation at all.
  322.  
  323.     This section describes standalone modules with UNsharable code because
  324.     the code is completely position independant and references only one set
  325.     of data.
  326.  
  327.                ________________
  328.  ANY ADDRESS IN RAM   |startup           |
  329.               |     CODE       |
  330.               |----------------|
  331.               | initialized    |
  332.               |    data        |
  333.               |----------------|
  334.               |            |
  335.               |     BSS        |
  336.               |----------------|
  337.  
  338.     The code uses a single PC-relative reference to find the start of the
  339.     data, then generates the A4 register to point to the data section.
  340.     NOT A SINGLE 32-BIT REFERENCE EXISTS.
  341.  
  342.     WARNING:    The module has only one set of data.  Once initialized data
  343.     is modified it stays modified through multiple invocations of the module
  344.  
  345.     The advantage of using a position independant module is obvious... you
  346.     can copy it to any point in ram as-is and then call it!  For small
  347.     68000 boxes with limited memory this is definite plus as it greatly
  348.     simplifies the loading mechanism.
  349.  
  350.     To create a 100% relocatable module, the code must be less than 32K
  351.     and the data less than 64K.  You must use the -pi option when compiling
  352.     all source modules, when running dlink, and when running ROMABLE.
  353.  
  354.     The -pi option, amoung other things, puts the __ABSOLUTE_BAS and
  355.     __DATA_BAS linker symbols in the code section.  Actually, dlink puts
  356.     the entire program into a single CODE hunk!
  357.  
  358.     dcc -c test.c -pi
  359.     dlink -pi rampi.o test.o -lrom -o test
  360.     romable test -o test.bin -pi
  361.  
  362.     RAMPI.A is something you have to write, but you do have a template.
  363.     Take a look at LIB/AMIGA/C_PI.A as an example (also note that
  364.     LIB/AMIGA/X.A is also required).  Remember that the autoinit sections
  365.     must be entirely supported though not necessarily the autoexit sections,
  366.     it depends on your application.
  367.  
  368.                 USING ROM.LIB
  369.  
  370.     ROM.LIB is generates from LIB/FILES.ROM3LIB and contains compiler
  371.     support routines that do not require any RAM.  Modules in the library
  372.     are entirely position independant.    If you use library calls instead
  373.     of macros in <ctype.h> for ctype functions those are position
  374.     independant as well ... they use pc-relative to access the lookup
  375.     tables (which are declared const).
  376.  
  377.     Nothing in ROM.LIB declares any data variables.  The idea is to link
  378.     your code with ROM.LIB instead of C.LIB to ensure that incompatible
  379.     routines are never included (instead you get an undefined symbol error
  380.     from the linker when you make a mistake).
  381.  
  382.     Warning: If you want position independant code you must compile with
  383.     -pi or -mS, especially when accessing <ctype.h> macros.
  384.  
  385.  
  386.  
  387.     ------------------------------------------------------------------------
  388.  
  389.     ROMABLE exeFile -o outFile [-o outFile2] -C addr -D addr -pi
  390.  
  391.     addr:   decimal, 0octal, or 0xHEX
  392.  
  393.     Romable generates a binary image for an executable compiled under DICE
  394.     and is normally used to generate a ROMABLE raw binary output file.
  395.  
  396.     exeFile     input executable linked with dlink
  397.  
  398.     -o outFile    output binary (unformatted -- raw).  If TWO -o options
  399.             are specified the two output files will have even bytes
  400.             and odd bytes respectively, which is what you need when
  401.             you must program two eproms (one on the LSB data lines
  402.             and one on the MSB data lines)
  403.  
  404.         example: -o out1        result: 01 02 03 04
  405.  
  406.         example: -o out1 -o out2    result (out1):  01 03
  407.                     result (out2):  02 04
  408.  
  409.  
  410.     -C addr     code start address, 0octal, decimal, or 0xHEX
  411.  
  412.     -D addr     data start address, 0octal, decimal, or 0xHEX
  413.  
  414.     -DC        place actual data+bss just after code (i.e. the
  415.             result is intended to be downloaded into RAM, there
  416.             is no duplicate data in this case).
  417.  
  418.             '-D addr' is not specified in this case
  419.  
  420.     -pi        generate a position independant module.  Neither
  421.             -C or -D are specified in this case, and ROMABLE
  422.             will warn you have any absolute references.
  423.  
  424.     Note that your custom startup code determines how much of __autoinit
  425.     and __autoexit is to be supported.    Note especially that __autoinit0
  426.     MUST BE SUPPORTED because DICE will generate __autoinit0 sections to
  427.     handle 32 bit data relocations run-time.
  428.  
  429.     ROMABLE generates a raw output file or files with the EPROM code first,
  430.     and initialized data after the main code (still in EPROM) which, as
  431.     has already been described, will be copied to RAM on reset by your
  432.     startup routine.
  433.  
  434.     This startup-copying of initialized data and clearing of BSS makes it
  435.     extremely easy to use DICE to generate ROMED applications without
  436.     having to deal with major porting considerations.
  437.  
  438.